package dormouse.vfs.metadata;

import java.io.IOException;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.VFS;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.sun.org.apache.xpath.internal.XPathAPI;

import dormouse.xml.XMLUtil;

/**
 * This class reads the metadata from an open office file.
 */
public class OpenOfficeMetadataReader extends AbstractMetaDataReader implements IMetadataReader {
    
    public static final String TITLE = "Title";
	private static final String MODIFICATION_DATE = "Modification Date";
	public static final String CREATION_DATE = "Creation Date";
	public static final String INITIAL_CREATOR = "Initial Creator";
	public static final String CREATOR = "Creator";

	/**
     * Constructor
     */
    public OpenOfficeMetadataReader(){
        setFileExtensions(new String[]{"odt","odp"});
    }

    /**
     * {@inheritDoc}
     * 
     * <office:document-meta office:version="1.1">
−
<office:meta>
−
<meta:generator>
OpenOffice.org/2.4$Unix OpenOffice.org_project/680m17$Build-9310
</meta:generator>
<dc:title>Test Document</dc:title>
−
<dc:description>
This is a  test document used to verify that we can read document properties.
</dc:description>
<dc:subject>Document Used To Test Properties</dc:subject>
<meta:initial-creator>Mark Fortner</meta:initial-creator>
<meta:creation-date>2008-06-21T07:18:47</meta:creation-date>
<dc:creator>Mark Fortner</dc:creator>
<dc:date>2008-06-22T20:45:15</dc:date>
<meta:keyword>Test</meta:keyword>
<meta:editing-cycles>0</meta:editing-cycles>
<meta:editing-duration>PT7H0M0S</meta:editing-duration>
<meta:user-defined meta:name="My Custom Field">This is my custom field</meta:user-defined>
<meta:user-defined meta:name="Info 2"/>
<meta:user-defined meta:name="Info 3"/>
<meta:user-defined meta:name="Info 4"/>
<meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="0" meta:word-count="0" meta:character-count="0"/>
</office:meta>
</office:document-meta>
     */
    @Override
    public Map<String, String> getMetadata(FileObject file) throws IOException{
    	FileObject fileSystem = VFS.getManager().createFileSystem("zip",file);
    	FileObject metaFile = fileSystem.getChild("meta.xml");
    	
    	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(false);

        // Create the builder and parse the file
        try {
        	factory.setNamespaceAware(true);
        	DocumentBuilder builder = factory.newDocumentBuilder();
        	
			Document doc = builder.parse(metaFile.getContent().getInputStream());
			
			XPathFactory  xpathFactory = XPathFactory.newInstance();
			XPath xpath = xpathFactory.newXPath();
			
			String dcNameSpaceURI = "http://purl.org/dc/elements/1.1";
			Element dcNameSpace = doc.createElementNS(dcNameSpaceURI, "dc:title");
			//Element officeNS = doc.createElementNS("", "office:document-meta");
			
			Element metaNode = (Element)XPathAPI.selectSingleNode(doc, "/office:document-meta/office:meta");
			
			
			this.metadata.put(CREATOR, XMLUtil.getSubNodeValueNS(metaNode, "creator","*"));
			
			Node initCreator = XPathAPI.selectSingleNode(doc, "/office:document-meta/office:meta/meta:initial-creator",doc);
			this.metadata.put(INITIAL_CREATOR, XMLUtil.getSubNodeValueNS(metaNode, "initial-creator","*"));
			
			Node creationDate = XPathAPI.selectSingleNode(doc, "/office:document-meta/office:meta/meta:creation-date",doc);
			this.metadata.put(CREATION_DATE, XMLUtil.getSubNodeValueNS(metaNode, "creation-date","*"));
			
			Node modDate = XPathAPI.selectSingleNode(doc, "/office:document-meta/office:meta/dc:date",doc);
			this.metadata.put(MODIFICATION_DATE, XMLUtil.getSubNodeValueNS(metaNode, "date","*"));
						
			Node title = XPathAPI.selectSingleNode(doc, "/office:document-meta/office:meta/dc:title",doc);
			this.metadata.put(TITLE, XMLUtil.getSubNodeValueNS(metaNode, "title","*"));
			
						
			Node description = XPathAPI.selectSingleNode(doc, "/office:document-meta/office:meta/dc:description",doc);
			this.metadata.put("Description", XMLUtil.getSubNodeValueNS(metaNode, "description", "*"));
			
			Node subject = XPathAPI.selectSingleNode(doc, "/office:document-meta/office:meta/dc:subject",doc);
			this.metadata.put("Subject", XMLUtil.getSubNodeValueNS(metaNode, "subject","*"));
			
			Element stats = XMLUtil.getSubNodeNS(metaNode, "document-statistic", "*");
			this.metadata.put("Table Count",stats.getAttribute("table-count"));
			this.metadata.put("Image Count",stats.getAttribute("image-count"));
			this.metadata.put("Object Count",stats.getAttribute("object-count"));
			this.metadata.put("Page Count",stats.getAttribute("page-count"));
			this.metadata.put("Paragraph Count",stats.getAttribute("paragraph-count"));
			this.metadata.put("Word Count", stats.getAttribute("word-count"));
			this.metadata.put("Character Count", stats.getAttribute("character-count"));

			
			// custom fields
			NodeList customFlds = metaNode.getElementsByTagNameNS("*", "user-defined"); 
			Element currNode = null;
			String name = null;
			String val = null;
			for (int i=0; i < customFlds.getLength(); i++){
				currNode = (Element)customFlds.item(i);
				name = currNode.getAttribute("name");
				val = currNode.getTextContent();
				this.metadata.put(name, val);
			}

        } catch (SAXException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		}
       
    	
        return this.metadata;
    }


  
}
